home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cocktail
/
front.lha
/
front
/
src
/
Errors.mi
< prev
next >
Wrap
Text File
|
1992-08-18
|
12KB
|
456 lines
(* handle and log errors *)
(* $Id: Errors.mi,v 2.4 1992/08/07 15:13:51 grosch rel $ *)
(* $Log: Errors.mi,v $
* Revision 2.4 1992/08/07 15:13:51 grosch
* allow several scanner and parsers; extend module Errors
*
* Revision 2.3 1992/01/30 13:34:33 grosch
* redesign of interface to operating system
*
* Revision 2.2 1991/11/21 14:47:50 grosch
* new version of RCS on SPARC
*
* Revision 2.1 91/03/19 14:47:01 grosch
* print error message if ErrorTab can not be opened
*
* Revision 2.0 91/03/08 18:26:17 grosch
* turned tables into initialized arrays (in C)
* moved mapping tokens -> strings from Errors to Parser
* changed interface for source position
*
* Revision 1.1 90/06/11 18:44:45 grosch
* layout improvements
*
* Revision 1.0 88/10/04 14:26:44 vielsack
* Initial revision
*
*)
IMPLEMENTATION MODULE Errors;
FROM IO IMPORT tFile, StdError, WriteC,
WriteNl, WriteS, WriteI,
WriteLong, WriteB, WriteR,
ReadOpen, ReadClose, EndOfFile,
CloseIO;
FROM Listing IMPORT tListMode, ListMode, PutError,
HasError, GetError;
FROM Memory IMPORT Alloc;
FROM Sets IMPORT tSet, MakeSet, IsElement,
Assign;
FROM Strings IMPORT tString, AssignEmpty, SubString,
Char, ReadL, Length,
ArrayToString, StringToInt;
FROM StringMem IMPORT tStringRef, PutString, GetString,
WriteString;
FROM Idents IMPORT tIdent, WriteIdent;
FROM SysError IMPORT StatIsBad, SysErrorMessageI;
FROM System IMPORT Exit;
FROM SYSTEM IMPORT ADDRESS, ADR, TSIZE;
FROM TokenTab IMPORT TokenError, TokenToSymbol, MAXTerm;
FROM Positions IMPORT tPosition, NoPosition;
IMPORT Strings;
CONST
eNone = 0 ; (* for internal use *)
cTab = 11C ; (* tab character *)
NoStringRef = -1 ;
MaxCode = 160 ;
eWrongClass = 16 ;
eWrongCode = 17 ;
VAR
NoReports : BOOLEAN;
ReportMode : tReportMode;
ErrorClassRef : ARRAY [0..MaxErrorClass] OF tStringRef;
ErrorCodeRef : ARRAY [0..MaxCode] OF tStringRef;
ErrorCountRef : ARRAY [0..MaxErrorClass] OF tStringRef;
i : CARDINAL; (* index to initialize date structure *)
PROCEDURE ErrorMessage (ErrorCode, ErrorClass: CARDINAL; Position: tPosition);
BEGIN
ErrorMessageI (ErrorCode, ErrorClass, Position, eNone, NIL);
END ErrorMessage;
PROCEDURE ErrorMessageI (ErrorCode, ErrorClass: CARDINAL; Position: tPosition;
InfoClass: CARDINAL; Info: ADDRESS);
BEGIN
INC (ErrorCount [ErrorClass]);
IF ErrorClass IN ReportClass THEN
NoReports := FALSE;
IF ReportMode = eImmediate THEN
WriteErrorMessage (ErrorCode, ErrorClass, Position.Line, Position.Column);
WriteInfo (InfoClass, Info);
WriteNl (StdError);
ELSE
KeepInfo (InfoClass, Info);
PutError (ErrorCode, ErrorClass, Position.Line, Position.Column, InfoClass, Info);
END;
END;
IF ErrorClass < 3 THEN Finish END;
END ErrorMessageI;
PROCEDURE SetReportMode (mode: tReportMode);
BEGIN
ReportMode := mode;
CASE ReportMode OF
eListing :
ListMode := Listing;
ELSE
ListMode := NoListing;
END;
END SetReportMode;
PROCEDURE BeginErrors;
VAR
i : CARDINAL;
f : tFile;
s : tString;
line : tString;
BEGIN
f := ReadOpen (ErrorTable);
IF StatIsBad (f) THEN
WriteS (StdError, 'Fatal error: cannot open ');
WriteS (StdError, ErrorTable);
WriteNl (StdError);
RETURN;
END;
LOOP
IF EndOfFile (f) THEN EXIT; END;
ReadL (f, line);
IF Char (line, 1) = '$' THEN EXIT; END;
IF Char (line, 1) # '%' THEN
SplitLine (line, i, s);
IF (i<0) OR (i>MaxErrorClass) THEN
ErrorMessageI (eWrongClass, eError, NoPosition, eString, ADR(line));
ELSE
ErrorClassRef [i] := PutString (s);
END;
END;
END;
LOOP
IF EndOfFile (f) THEN EXIT; END;
ReadL (f, line);
IF Char (line, 1) = '$' THEN EXIT; END;
IF Char (line, 1) # '%' THEN
SplitLine (line, i, s);
IF (i<0) OR (i>MaxCode) THEN
ErrorMessageI (eWrongCode, eError, NoPosition, eString, ADR(line));
ELSE
ErrorCodeRef [i] := PutString (s);
END;
END;
END;
LOOP
IF EndOfFile (f) THEN EXIT; END;
ReadL (f, line);
IF Char (line, 1) = '$' THEN EXIT; END;
IF Char (line, 1) # '%' THEN
SplitLine (line, i, s);
IF (i<0) OR (i>MaxErrorClass) THEN
ErrorMessageI (eWrongClass, eError, NoPosition, eString, ADR(line));
ELSE
ErrorCountRef [i] := PutString (s);
END;
END;
END;
ReadClose (f);
END BeginErrors;
PROCEDURE CloseErrors ();
VAR
i : CARDINAL;
r : tStringRef;
ErrorCode, ErrorClass, Line, Column, InfoClass: CARDINAL;
Info : ADDRESS;
BEGIN
IF NoReports THEN RETURN END;
WHILE HasError() DO
GetError (ErrorCode, ErrorClass, Line, Column, InfoClass, Info);
WriteErrorMessage (ErrorCode, ErrorClass, Line, Column);
WriteInfo (InfoClass, Info);
WriteNl (StdError);
END;
FOR i := 0 TO MaxErrorClass DO
IF ErrorCount [i] > 0 THEN
WriteS (StdError, ' ');
WriteI (StdError, ErrorCount [i], 1);
WriteC (StdError, ' ');
r := ErrorCountRef [i];
IF r = NoStringRef THEN
WriteS (StdError, 'in error class ');
WriteI (StdError, i, 1);
ELSE
WriteString (StdError, r);
END;
END;
END;
WriteNl (StdError);
END CloseErrors;
PROCEDURE WriteErrorMessage (ErrorCode, ErrorClass, Line, Column: CARDINAL);
VAR r : tStringRef;
BEGIN
IF (ReportMode # eListing) & (Line # 0) THEN
WriteI (StdError, Line, 3);
WriteS (StdError, ', ');
END;
IF Column # 0 THEN
WriteI (StdError, Column, 2);
WriteS (StdError, ': ');
END;
IF (ErrorClass > MaxErrorClass) OR (ErrorClass < 0) THEN
WriteS (StdError, 'Error class: ');
WriteI (StdError, ErrorClass, 1);
ELSE
r := ErrorClassRef [ErrorClass];
IF r = NoStringRef THEN
WriteS (StdError, 'Error class: ');
WriteI (StdError, ErrorClass, 1);
ELSE
WriteString (StdError, r);
END;
END;
IF (ErrorCode > MaxCode) OR (ErrorCode < 0) THEN
IF ErrorCode >= SysOffset THEN
WriteS (StdError, ' system error code: ');
WriteI (StdError, ErrorCode - SysOffset, 1);
ELSE
WriteS (StdError, ' error code: ');
WriteI (StdError, ErrorCode, 1);
END;
ELSE
r := ErrorCodeRef [ErrorCode];
IF r = NoStringRef THEN
IF ErrorCode >= SysOffset THEN
WriteS (StdError, ' system error code: ');
WriteI (StdError, ErrorCode - SysOffset, 1);
ELSE
WriteS (StdError, ' error code: ');
WriteI (StdError, ErrorCode, 1);
END;
ELSE
WriteString (StdError, r);
END;
END;
END WriteErrorMessage;
PROCEDURE KeepInfo (InfoClass: CARDINAL; VAR Info: ADDRESS);
VAR
InfPtrToInteger, PtrToInteger : POINTER TO INTEGER;
InfPtrToShort, PtrToShort : POINTER TO SHORTCARD;
InfPtrToLong, PtrToLong : POINTER TO LONGINT;
InfPtrToReal, PtrToReal : POINTER TO REAL;
InfPtrToBoolean, PtrToBoolean : POINTER TO BOOLEAN;
InfPtrToCharacter,PtrToCharacter : POINTER TO CHAR;
InfPtrToString, PtrToString : POINTER TO tString;
InfPtrToArray, PtrToArray : POINTER TO ARRAY [0..255] OF CHAR;
InfPtrToSet, PtrToSet : POINTER TO tSet;
InfPtrToIdent, PtrToIdent : POINTER TO tIdent;
BEGIN
IF InfoClass = eNone THEN RETURN END;
CASE InfoClass OF
| eInteger:
InfPtrToInteger := Alloc (TSIZE (INTEGER));
PtrToInteger := Info;
InfPtrToInteger^ := PtrToInteger^;
Info := InfPtrToInteger;
| eShort:
InfPtrToShort := Alloc (TSIZE (SHORTCARD));
PtrToShort := Info;
InfPtrToShort^ := PtrToShort^;
Info := InfPtrToShort;
| eLong:
InfPtrToLong := Alloc (TSIZE (LONGINT));
PtrToLong := Info;
InfPtrToLong^ := PtrToLong^;
Info := InfPtrToLong;
| eReal:
InfPtrToReal := Alloc (TSIZE (REAL));
PtrToReal := Info;
InfPtrToReal^ := PtrToReal^;
Info := InfPtrToReal;
| eBoolean:
InfPtrToBoolean := Alloc (TSIZE (BOOLEAN));
PtrToBoolean := Info;
InfPtrToBoolean^ := PtrToBoolean^;
Info := InfPtrToBoolean;
| eCharacter:
InfPtrToCharacter := Alloc (TSIZE (CHAR));
PtrToCharacter := Info;
InfPtrToCharacter^ := PtrToCharacter^;
Info := InfPtrToCharacter;
| eString:
InfPtrToString := Alloc (TSIZE (tString));
PtrToString := Info;
Strings.Assign (InfPtrToString^, PtrToString^);
Info := InfPtrToString;
| eArray:
InfPtrToArray := Alloc (256);
PtrToArray := Info;
InfPtrToArray^ := PtrToArray^;
Info := InfPtrToArray;
| eIdent:
InfPtrToIdent := Alloc (TSIZE (tIdent));
PtrToIdent := Info;
InfPtrToIdent^ := PtrToIdent^;
Info := InfPtrToIdent;
| eTermSet:
InfPtrToSet := Alloc (TSIZE (tSet));
PtrToSet := Info;
MakeSet (InfPtrToSet^, PtrToSet^.MaxElmt);
Assign (InfPtrToSet^, PtrToSet^);
Info := InfPtrToSet;
ELSE
END;
END KeepInfo;
PROCEDURE WriteInfo (InfoClass: CARDINAL; Info: ADDRESS);
VAR
PtrToInteger : POINTER TO INTEGER;
PtrToShort : POINTER TO SHORTCARD;
PtrToLong : POINTER TO LONGINT;
PtrToReal : POINTER TO REAL;
PtrToBoolean : POINTER TO BOOLEAN;
PtrToCharacter : POINTER TO CHAR;
PtrToString : POINTER TO tString;
PtrToArray : POINTER TO ARRAY [0..255] OF CHAR;
PtrToSet : POINTER TO tSet;
PtrToIdent : POINTER TO tIdent;
BEGIN
IF InfoClass = eNone THEN RETURN END;
WriteC (StdError, ' ');
CASE InfoClass OF
| eInteger:
PtrToInteger := Info;
WriteI (StdError, PtrToInteger^, 1);
| eShort:
PtrToShort := Info;
WriteI (StdError, PtrToShort^, 1);
| eLong:
PtrToLong := Info;
WriteLong (StdError, PtrToLong^, 1);
| eReal:
PtrToReal := Info;
WriteR (StdError, PtrToReal^, 1, 10, 1);
| eBoolean:
PtrToBoolean := Info;
WriteB (StdError, PtrToBoolean^);
| eCharacter:
PtrToCharacter := Info;
WriteC (StdError, PtrToCharacter^);
| eString:
PtrToString := Info;
Strings.WriteS (StdError, PtrToString^);
| eArray:
PtrToArray := Info;
WriteS (StdError, PtrToArray^);
| eIdent:
PtrToIdent := Info;
WriteIdent (StdError, PtrToIdent^);
| eTermSet:
PtrToSet := Info;
WriteTermSet (StdError, PtrToSet^);
ELSE WriteS (StdError, 'Info Class: ');
WriteI (StdError, InfoClass, 1);
END;
END WriteInfo;
PROCEDURE WriteTermSet (f: tFile; s:tSet);
VAR i : CARDINAL;
Error: TokenError;
BEGIN
FOR i := 0 TO MAXTerm DO
IF IsElement (i, s) THEN
WriteS (f, ' ');
WriteIdent (f, TokenToSymbol (i, Error));
END;
END;
END WriteTermSet;
PROCEDURE SplitLine (line: tString; VAR i: CARDINAL; VAR s1: tString);
VAR
m, p1, p2 : CARDINAL;
s : tString;
BEGIN
p1 := 1;
p2 := 1;
m := Length (line);
LOOP
IF p2 > m THEN EXIT; END;
IF Char (line, p2) = cTab THEN EXIT; END;
INC (p2);
END;
DEC (p2);
IF p1 > p2 THEN
i := 0;
ELSE
SubString (line, p1, p2, s);
i := StringToInt (s);
END;
p1 := p2+1;
LOOP
IF p1 > m THEN EXIT; END;
IF Char (line, p1) # cTab THEN EXIT; END;
INC (p1);
END;
p2 := p1;
LOOP
IF p2 > m THEN EXIT; END;
IF Char (line, p2) = cTab THEN EXIT; END;
INC (p2);
END;
DEC (p2);
IF p1 > p2 THEN
AssignEmpty (s1);
ELSE
SubString (line, p1, p2, s1);
END;
END SplitLine;
PROCEDURE Finish;
BEGIN
CloseErrors;
CloseIO;
Exit (1);
END Finish;
BEGIN
NoReports := TRUE;
ReportMode := eNoListing;
ErrorTable := 'ErrorTab';
ReportClass := {0..MaxErrorClass};
FOR i := 0 TO MaxErrorClass DO
ErrorCount [i] := 0;
END;
FOR i := 0 TO MaxErrorClass DO
ErrorClassRef [i] := NoStringRef;
END;
FOR i := 0 TO MaxCode DO
ErrorCodeRef [i] := NoStringRef;
END;
FOR i := 0 TO MaxErrorClass DO
ErrorCountRef [i] := NoStringRef;
END;
END Errors.